package com.sdonkey.score.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sdonkey.score.bean.*;
import com.sdonkey.score.dao.IAdScoreManagerDao;
import com.sdonkey.score.dao.IMyAdsDao;
import com.sdonkey.score.dao.IUserAccountDao;
import com.sdonkey.score.dto.ScoreDetailsDto;
import com.sdonkey.score.dto.UserExtractDto;
import com.sdonkey.score.dto.UserTowardBalanceDto;
import com.sdonkey.score.service.IAdScoreManagerService;
import com.sdonkey.score.util.*;
import org.apache.ibatis.annotations.Param;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author 赵超
 */
@Service
public class AdScoreManagerServiceImpl implements IAdScoreManagerService {
    private Logger logger = Logger.getLogger(AdScoreManagerServiceImpl.class);

    @Autowired
    IAdScoreManagerDao adScoreManagerDao;
    @Autowired
    IUserAccountDao userAccountDao;

    private String getOrderId() {
        long time = System.currentTimeMillis();
        int a = (int) (Math.random() * 9000 + 1000);
        String orderid = "no_" + time + a;
        return orderid;
    }

    @Override
    public UserBalanceBean selectUserBalance(String id) {
        return adScoreManagerDao.selectUserBalance(id);
    }

    @Override
    public Map<String, Object> extractRecordsByDate(String id, String startTime, String endTime, int page) {
        if (!FormValidateUtil.isEmpty(startTime) && !FormValidateUtil.isEmpty(endTime)) {
            String[] times = endTime.split("-");
            String time = times[2];
            time = (Integer.parseInt(time) + 1) + "";
            endTime = times[0] + "-" + StringUtil.getTimeStr(times[1]) + "-" + StringUtil.getTimeStr(time);
        }
        PageHelper.startPage(page, StaticVariable.page_logs_num);
        Page<UserExtractDto> userExtractList = (Page<UserExtractDto>) adScoreManagerDao.extractRecordsByDate(id, startTime, endTime);
        Map<String, Object> map = new HashMap<String, Object>();
        if (userExtractList != null && userExtractList.size() > 0 && userExtractList.get(0).getCreateTime() != null) {
            for (UserExtractDto userExtractDto : userExtractList) {
                userExtractDto.setBankCardNum(
                        (AccountUtil.getAccountNum(AccountUtil.fourNumbers, userExtractDto.getAccountNum()) + ""));
                userExtractDto.setAccountUserName(AccountUtil.getAccountUserName(userExtractDto.getAccountUserName()));
            }
            map.put("status", "1");
            map.put("nowpage", userExtractList.getPageNum());
            map.put("sumpage", userExtractList.getPages());
        } else {
            map.put("status", "0");
            map.put("nowpage", 1);
            map.put("sumpage", 1);
        }
        map.put("userExtractList", userExtractList);
        return map;
    }

    @Override
    public UserExtractDto selectExtractDetail(String id) {
        UserExtractDto userExtractDto = adScoreManagerDao.selectExtractDetail(id);
        userExtractDto.setBankCardNum(
                (AccountUtil.getAccountNum(AccountUtil.onlyShowFourNumbers, userExtractDto.getAccountNum()) + ""));
        return userExtractDto;
    }

    @Override
    public int addNote(String id, String note) {
        return adScoreManagerDao.addNote(id, note);
    }

    @Override
    public Map<String, Object> selectMyScore(String userid, int page) {
        PageHelper.startPage(page, StaticVariable.page_logs_num);
        Page<UserTowardBalanceDto> userTowardBalanceDtoList = (Page<UserTowardBalanceDto>) adScoreManagerDao
                .selectMyScore(userid);
        Map<String, Object> map = new HashMap<String, Object>();
        if (userTowardBalanceDtoList != null && userTowardBalanceDtoList.size() > 0) {
            map.put("nowpage", userTowardBalanceDtoList.getPageNum());
            map.put("sumpage", userTowardBalanceDtoList.getPages());
        } else {
            map.put("nowpage", 1);
            map.put("sumpage", 1);
        }
        map.put("userTowardBalanceDtoList", userTowardBalanceDtoList.getResult());
        return map;
    }

    @Override
    public Map<String, Object> selectProductions(String developerId, int page) {
        // 之后可能需要添加分页功能
        // PageHelper.startPage(page, StaticVariable.page_logs_num);
        // Page<UserTowardBalanceDto> applicationList =
        // (Page<UserTowardBalanceDto>)
        // adScoreManagerDao.selectProductions(developerId);

        DeveloperBean developerBean = adScoreManagerDao.selectDevInfoById(developerId);
        List<UserTowardBalanceDto> userTowardBalanceList = adScoreManagerDao.selectProductions(developerId);
        List<ApplicationNewBean> applicationList = new ArrayList<ApplicationNewBean>();
        UserTowardBalanceDto userTowardBalanceDto = new UserTowardBalanceDto();
        for (UserTowardBalanceDto userTowardBalanceD : userTowardBalanceList) {
            ApplicationNewBean application = userTowardBalanceD.getApplication();
            if (FormValidateUtil.isNotEmpty(application.getLogourl())) {
                application.setLogourl(StaticVariable.picurladdr + application.getLogourl());
            }
            applicationList.add(application);
        }
        userTowardBalanceDto.setApplicationList(applicationList);
        if (developerBean != null) {
            if (developerBean.getLogo() != null && developerBean.getLogo() != "") {
                developerBean.setLogo(StaticVariable.picurladdr + developerBean.getLogo());
            }
            userTowardBalanceDto.setDeveloper(developerBean);
        }
        // 实现分类查询的代码块
        /*
		 * Integer maxType =
		 * adScoreManagerDao.getProductionMaxApplicationType(developerId);
		 * Map<Integer, Integer> count = new HashMap<Integer,Integer>(); for(int
		 * i = 1; i <= maxType; i++) { count.put(maxType,
		 * adScoreManagerDao.selectCountByAppType(i)); }
		 * userTowardBalanceDto.setCount(count);
		 */

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("userTowardBalanceDto", userTowardBalanceDto);
        return map;
    }

    @Override
    public UserTowardBalanceDto selectproductionDetail(String applicationId) {
        UserTowardBalanceDto dto = adScoreManagerDao.selectProductionDetail(applicationId);
        if (dto != null && dto.getApplication() != null) {
            dto.getApplication().setLogourl(StaticVariable.picurladdr + dto.getApplication().getLogourl());
        }
        return dto;
    }

    @Override
    @Transactional
    public int buyProduction(String id, String applicationId, Double price) {
        int flag;
        try {
            adScoreManagerDao.insertRecord_To_Output(getOrderId(), id, applicationId,
                    adScoreManagerDao.selectDevloperId(applicationId),
                    adScoreManagerDao.selectDevloperName(adScoreManagerDao.selectDevloperId(applicationId)),
                    price + "", ScoreHelper.getDealType(ScoreHelper.payForApp));
            adScoreManagerDao.update_TowardBalance_Reduce(id, price + "");
            // 向购买记录表格里面添加一条购买记录，application表里面增加一次下载次数
            // adScoreManagerDao.updateAppDownloadTimes(applicationId);
            flag = 1;
            logger.info("用户" + id + " 购买应用" + applicationId + " 支出" + price);
        } catch (Exception e) {
            logger.error("用户" + id + " 购买应用" + applicationId + " 支出" + price + " 失败", e);
            flag = 0;
        }
        return flag;
    }

    @Override
    public boolean validatePayPsw(String userId, String payPsw) {
        int flag = adScoreManagerDao.validatePayPsw(userId, MD5.encode(payPsw));
        if (flag == 1) {
            return true;
        }
        return false;
    }

    @Override
    @Transactional
    public int payToDeveloperExecute(String userId, String developerId, String outBalance, String note) {
        try {
            int i = userAccountDao.update_Balance(userId, outBalance);
            if (i > 0) {
                adScoreManagerDao.payToDeveloperExecute(developerId, outBalance);
                //adScoreManagerDao.update_TowardBalance_Reduce(userId, outBalance); // 这里修改的是专项积分
                adScoreManagerDao.insertRecord_To_DevTransfer(getOrderId(), developerId, userId, ScoreHelper.NORMAL_USER,
                        outBalance, note, ScoreHelper.IMMEDIATELY);
                adScoreManagerDao.insertRecord_To_Output(getOrderId(), userId, null, developerId,
                        adScoreManagerDao.selectDevloperName(developerId), outBalance,
                        ScoreHelper.getDealType(ScoreHelper.payForApp)); // 应用购买
                adScoreManagerDao.insertRecord_To_TransferRecords(getOrderId(), userId, developerId, ScoreHelper.DEVELOPER,
                        outBalance, ScoreHelper.IMMEDIATELY, note);
                logger.info("用户" + userId + " 向内容商" + developerId + "转账 支出" + outBalance);
                return 1;
            }
            return -1;
        } catch (Exception e) {
            logger.error("用户" + userId + " 向内容商" + developerId + "转账 支出" + outBalance + " 失败", e);
            return 0;
        }
    }

    @Override
    public Map<String, Object> friendListByID(String id) {
        Map<String, Object> map = new HashMap<String, Object>();
        List<FriendBean> friendList = userAccountDao.friendListByID(id);
        List<FriendBean> friendsList = new ArrayList<FriendBean>();
        if (friendList != null) {
            for (FriendBean friendBean : friendList) {
                if (friendBean != null) {
                    if (friendBean.getImage_url() == null) {
                        friendBean.setImage_url("");
                    } else {
                        friendBean.setImage_url(StaticVariable.user_head_url + friendBean.getImage_url());
                    }
                    friendsList.add(friendBean);
                }
            }
        }
        map.put("friendsList", friendsList);
        return map;
    }

    @Override
    @Transactional
    public int payToFriendExecute(String userId, String friendId, String outBalance, String note) {
        try {
            int i = userAccountDao.update_Balance(userId, outBalance);
            if (i > 0) {
                adScoreManagerDao.payToFriendExecute(friendId, outBalance);
                adScoreManagerDao.insertRecord_To_Income(getOrderId(), friendId, userId, adScoreManagerDao.selectUsername(userId),
                        outBalance, ScoreHelper.getDealType(ScoreHelper.transferToFriend));
                adScoreManagerDao.insertRecord_To_Output(getOrderId(), userId, null, friendId,
                        adScoreManagerDao.selectUsername(friendId), outBalance,
                        ScoreHelper.getDealType(ScoreHelper.transferToFriend));
                adScoreManagerDao.insertRecord_To_TransferRecords(getOrderId(), userId, friendId, ScoreHelper.NORMAL_USER,
                        outBalance, ScoreHelper.IMMEDIATELY, note);
                logger.info("用户" + userId + " 向好友" + friendId + " 转账 支出" + outBalance);
                return 1;
            }
            return -1;
        } catch (Exception e) {
            logger.error("用户" + userId + " 向好友" + friendId + " 转账 支出" + outBalance + " 失败", e);
            return 0;
        }
    }

    @Override
    public List<TransferRecordBean> selectTransferRecords(String userId) {
        return adScoreManagerDao.selectTransferRecords(userId);
    }

    @Override
    public String select_TowardBalance(String id) {
        return adScoreManagerDao.select_TowardBalance(id);
    }

    @Override
    public Map<String, Object> selectScoreDetails(String userId, int page, String paymentType, String transferType,
                                                  String startTime, String endTime) {
        // 设置一个条件（时间、交易类型）查询标记，conditionFlag不为null的时候才会按条件（时间、交易类型）查询
        String conditionFlag = null;
        if (!FormValidateUtil.isEmpty(transferType)
                || (!FormValidateUtil.isEmpty(startTime) && !FormValidateUtil.isEmpty(endTime))) {
            conditionFlag = "1";
            if (!FormValidateUtil.isEmpty(startTime) && !FormValidateUtil.isEmpty(endTime)) {
                String[] times = endTime.split("-");
                String time = times[2];
                time = (Integer.parseInt(time) + 1) + "";
                endTime = times[0] + "-" + StringUtil.getTimeStr(times[1]) + "-" + StringUtil.getTimeStr(time);
            }
        }
        if (FormValidateUtil.isNotEmpty(transferType)) {
            Integer type;
            try {
                type = Integer.valueOf(transferType);
            } catch (NumberFormatException e) {
                type = 0;
            }
            transferType = ScoreHelper.getDealType(type);
        }
        Page<ScoreDetailsDto> listAll = new Page<>();
        Page<ScoreDetailsDto> incomeRecordList = new Page<>();
        Page<ScoreDetailsDto> outputRecordList = new Page<>();
        // 按照paymentType收支类型查询
        if (!FormValidateUtil.isEmpty(paymentType) && "1".equals(paymentType.trim())) {
            PageHelper.startPage(page, StaticVariable.scoreDetail_num);
            // 查询收入记录
            incomeRecordList = (Page<ScoreDetailsDto>) adScoreManagerDao.select_IncomeRecord(userId, paymentType,
                    transferType, startTime, endTime, conditionFlag);
        } else if (!FormValidateUtil.isEmpty(paymentType) && "-1".equals(paymentType.trim())) {
            PageHelper.startPage(page, StaticVariable.scoreDetail_num);
            // 查询支出记录
            outputRecordList = (Page<ScoreDetailsDto>) adScoreManagerDao.select_OutputRecord(userId, paymentType,
                    transferType, startTime, endTime, conditionFlag);
        } else {
            // 若没有收支类型的查询条件 加载出所有
            PageHelper.startPage(page, StaticVariable.scoreDetail_num);
            listAll = (Page<ScoreDetailsDto>) adScoreManagerDao.selectAllDetail(userId, transferType, startTime, endTime, conditionFlag);

        }
        List<ScoreDetailsDto> scoreDetailList = new ArrayList<ScoreDetailsDto>();
        if (incomeRecordList != null && incomeRecordList.size() > 0) {
            scoreDetailList.addAll(incomeRecordList);
        }
        if (outputRecordList != null && outputRecordList.size() > 0) {
            scoreDetailList.addAll(outputRecordList);
        }
        if (listAll != null && listAll.size() > 0) {
            scoreDetailList.addAll(listAll);
        }

        Map<String, Object> map = new HashMap<String, Object>();
        if (listAll.size() > 0) {
            map.put("nowpage", listAll.getPageNum());
            map.put("sumpage", listAll.getPages());
        } else if (outputRecordList.size() > 0) {
            map.put("nowpage", outputRecordList.getPageNum());
            map.put("sumpage", outputRecordList.getPages());
        } else if (incomeRecordList.size() > 0) {
            map.put("nowpage", incomeRecordList.getPageNum());
            map.put("sumpage", incomeRecordList.getPages());
        } else {
            map.put("nowpage", 1);
            map.put("sumpage", 1);
        }
        map.put("scoreDetailList", scoreDetailList);
        return map;
    }

    @Override
    @Transactional
    public int transOutToBankCardExecute(String userId, String outBalance, String serviceCost, String accountId) {
        int flag;
        try {
            // 提现到银行卡 等待介入银行
            // adScoreManagerDao.转入银行卡
            userAccountDao.update_Balance(userId, outBalance);
            String bankName = adScoreManagerDao.getBankName(accountId);
            adScoreManagerDao.insertRecord_To_Output(getOrderId(), userId, null, accountId, bankName, outBalance,
                    ScoreHelper.getDealType(ScoreHelper.transferToBank));
            int i = adScoreManagerDao.insertRecord_ToExtract(getOrderId(), userId, accountId, "安全保障到帐",
                    ScoreHelper.EXTRACT_QUICKLY, bankName, outBalance, serviceCost, "0");
            if (!(i > 0)) {
                adScoreManagerDao.insertRecord_ToExtract(getOrderId(), userId, accountId, "安全保障到帐", ScoreHelper.EXTRACT_QUICKLY,
                        bankName, outBalance, serviceCost, "-1");
            }
            flag = 1;
            logger.info("用户" + userId + " 提现到银行卡" + accountId + " 支出" + outBalance + " 手续费" + serviceCost);
        } catch (Exception e) {
            logger.error("用户" + userId + " 提现到银行卡" + accountId + " 支出" + outBalance + " 手续费" + serviceCost + " 失败", e);
            flag = 0;
        }
        return flag;
    }

    @Override
    public Double selectPriceByAppId(String applicationId) {
        return adScoreManagerDao.getPriceBuyAppId(applicationId);
    }

    @Override
    public List<ApplicationNewBean> loadDevApp(String developerId) {
        List<ApplicationNewBean> list = adScoreManagerDao.loadDevApp(developerId);
        for (ApplicationNewBean application : list) {
            application.setLogourl(StaticVariable.picurladdr + application.getLogourl());
        }
        return list;
    }

    @Override
    public DeveloperBean selectDevInfoById(String id) {
        return adScoreManagerDao.selectDevInfoById(id);
    }

    @Override
    public FriendBean selectFriendInfoById(String id) {
        Integer fid;
        try {
            fid = Integer.parseInt(id);
        } catch (Exception e) {
            fid = 0;
        }
        return userAccountDao.selectFriendByFid(fid);
    }

    @Override
    public List<DeveloperBean> devListByID(String userId) {
        List<DeveloperBean> list = adScoreManagerDao.devListById(userId);
        for (DeveloperBean developerBean : list) {
            if (FormValidateUtil.isNotEmpty(developerBean.getLogo())) {
                developerBean.setLogo(StaticVariable.picurladdr + developerBean.getLogo());
            }
        }
        return list;
    }

    @Override
    public int transferToBankFailed(String userId, String outBalance, String serviceCost) {
        double balance = Double.parseDouble(outBalance);
        double cost;
        try {
            cost = Double.parseDouble(serviceCost);
        } catch (Exception e) {
            logger.error("提现到银行卡失败之后，给用户" + userId + "退回 提现金额" + outBalance + " 手续费" + serviceCost + " 失败", e);
            cost = 0.0;
        }
        outBalance = balance + cost + "";
        return adScoreManagerDao.transferToBankFailed(userId, outBalance);
    }

    @Override
    @Transactional
    public int payToAppExecute(String userId, String appId, String outBalance, String note) {
        //向应用支付的方法
        //todo 还需添加购买应用之后的服务 如充值到绑定账号等
        try {
            int i = userAccountDao.update_Balance(userId, outBalance);
            if (i > 0) {
                adScoreManagerDao.insertRecord_To_Output(getOrderId(), userId, null, appId,
                        adScoreManagerDao.selectAppInfoByAid(appId).getName(), outBalance,
                        ScoreHelper.getDealType(ScoreHelper.payForApp));
                String devId = adScoreManagerDao.selectDevloperId(appId);
                adScoreManagerDao.payToDeveloperExecute(devId, outBalance);
                adScoreManagerDao.insertRecord_To_TransferRecords(getOrderId(), userId, appId, ScoreHelper.APPLICATION,
                        outBalance, ScoreHelper.IMMEDIATELY, note);
                logger.info("用户" + userId + " 向应用" + appId + "转账 支出" + outBalance);
                return 1;
            }
            return -1;
        } catch (Exception e) {
            logger.error("用户" + userId + " 向应用" + appId + "转账 支出" + outBalance + " 失败", e);
            return 0;
        }
    }

    @Override
    public ApplicationNewBean selectAppInfoByAid(String appId) {
        return adScoreManagerDao.selectAppInfoByAid(appId);
    }

    @Override
    public List<ApplicationNewBean> searchAppByCondition(String userId, String condition) {
        List<ApplicationNewBean> appList = adScoreManagerDao.searchAppByCondition(null, condition);
        if (appList != null && appList.size() > 0) {
            for (ApplicationNewBean app : appList) {
                app.setLogourl(StaticVariable.picurladdr + app.getLogourl());
            }
        }
        return appList;
    }

    @Override
    public Double getTowardBalanceByAppId(String userId, String appId) {
        Double balance = adScoreManagerDao.getTowardBalanceByAppId(userId, appId);
        if (balance == null) balance = 0.0;
        return balance;
    }

}
